/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.foxline.service;

import br.com.foxline.atlasmobile.enums.TipoDocumento;
import br.com.foxline.enums.Reports;
import br.com.foxline.model.Imovel;
import br.com.foxline.model.Proprietario;
import br.com.foxline.model.Registration;
import br.com.foxline.model.TypeRegistration;
import br.com.foxline.util.Extenso;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.Query;

/**
 *
 * @author luciano
 */
@Stateless
public class RegistrationService extends GenericService<Registration> {

    @EJB
    private ConfiguracaoService configuracaoService;

    public RegistrationService() {
        super(Registration.class);
    }

    @Override
    public void save(Registration entity) {
        entity.setDataAverbacao(new Date());
        super.save(entity);
    }

    public List<Registration> getByImovel(Imovel imovel) {
        String sql = "SELECT r FROM Registration r WHERE r.imovel= :imovel order by r.dataAverbacao desc";
        Query query = getEntityManager().createQuery(sql);
        query.setParameter("imovel", imovel);

        if (query.getResultList() != null) {
            return (List<Registration>) query.getResultList();
        }
        return new ArrayList<Registration>();

    }

    public void printRegistration(Registration registration) {
        if (registration.getRegistration() != null) {
            registration.setRegistration(find(registration.getRegistration().getId()));
        }
        if (registration.getTipoAverbacao().equals(TypeRegistration.TRANSFERENCIA)) {
            printRegistrationTransferencia(registration);
        } else if (registration.getTipoAverbacao().equals(TypeRegistration.MUDANCA_NOME)) {
            printRegistrationMudancaDeNome(registration);
        } else if (registration.getTipoAverbacao().equals(TypeRegistration.DESMEMBRAMENTO)) {
        }
    }

    public String getTextoAverbacao(Registration registration) {
        if (registration.getRegistration() == null) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        sb.append("Averb. Nº ");
        sb.append(registration.getRegistration().getId());
        sb.append(", Livro Nº ");
        sb.append(registration.getRegistration().getLivro());
        sb.append(" às fls Nº ");
        sb.append(registration.getRegistration().getFolhas());
        return sb.toString();
    }

    private void printRegistrationTransferencia(Registration registration) {
        printAverbacao(registration, getNomeProprietarios(registration.getTransmitente()), getNomeProprietarios(registration.getAdquirente()));
    }

    private void printRegistrationMudancaDeNome(Registration registration) {
        printAverbacao(registration, registration.getNomeAnterior(), registration.getNomeAtual());
    }

    private void printAverbacao(Registration registration, String foreiro, String adquirente) {
        HashMap parametros = new HashMap();
        StringBuilder texto = new StringBuilder();

        texto.append("    Certifico de ordem do Sr. Prefeito Municipal e à vista do processo e demais assentamentos nesta Repartição,");
        texto.append(" que da(s) Averbação ( ");
        texto.append(getTextoAverbacao(registration));
        texto.append(" )foreiro (a) (");
        texto.append(inBoldAndUnderline(foreiro));
        texto.append(") foi transmitida, a seu pedido por petição número ");
        texto.append(registration.getNumeroPeticao());
        texto.append(" de ");
        texto.append(formatDate(registration.getDataPeticao()));
        texto.append(" para o(a) Sr.: (");
        texto.append(inBoldAndUnderline(adquirente));
        texto.append("), conforme (Instrumento Público) ");
        texto.append(registration.getInstrumentoPublico());
        texto.append(", lavrado no ");
        texto.append(registration.getCartorio());
        texto.append(", (Livro Nº ");
        texto.append(registration.getLivroCartorio());
        texto.append(", fls Nº ");
        texto.append(registration.getFolhasCartorio());
        texto.append(") a área de (");
        texto.append(registration.getImovel().getDimensoes().getAreaTerreno());
        texto.append("m2): com a seguinte delimitação");

        StringBuilder dimensao = new StringBuilder();
        dimensao.append(" FRENTE: ");
        dimensao.append(registration.getImovel().getFrente());
        dimensao.append(", LADO DIREITO: ");
        dimensao.append(registration.getImovel().getLadoDireito());
        dimensao.append(", LADO ESQUERDO: ");
        dimensao.append(registration.getImovel().getLadoEsquerdo());
        dimensao.append(", FUNDO: ");
        dimensao.append(registration.getImovel().getFundo());

        texto.append(inBoldAndUnderline(dimensao.toString()));

        texto.append(" tendo sido feita a respectiva averbação na(s) Cartas de Aforamento supra citada(s) e no livro próprio desta Repartição em ");
        texto.append(dataPorExtenso(registration.getDataAverbacao()));
        texto.append(". <br/>");
        texto.append("    O novo foreiro sujeita-se a todas disposições contidas na legislação municipal sobre o assunto e inerentes às Cartas de Aforamento, salientando-se as seguintes obrigações:<br/>");
        texto.append("   1. Fica por se e seus herdeiros obrigados ao pagamento anual do fôro de R$ 0,020 centavos por metro quadrado.<br/>");
        texto.append("   2. Satisfarão pagamento dos fôros dentro de cada ano em curso , exceto o primeiro pagamento que é feito antes da expedição do presente título.<br/>");
        texto.append("   3. Na falta de pagamento no prazo acima marcado, pagará mais a multa de 10%.<br/>");
        texto.append("   4. O fôro do primeiro ano integral qualquer que seja o mês em que se utilize aforamento.<br/>");
        texto.append("   5. Perderá o direito do aforamento o terreno, voltando ele ao domínio útil do Município, depois de processado o comisso, quando não edificado ou beneficiado se deixar de pagar o fôro de trẽs anos consecutivos.<br/>");
        texto.append("   6. Reconhece não obstante a pena de comisso, o dever em que fica de pagar todos os fôros e multas devidas pelo tempo em que esteve em posse do terreno.<br/>");
        texto.append("   7. Além dos foros e multas da cláusula terceirapagará mais a multa especial R$ pela falta de pagamento por três anos consecutivos, dos foros do seu terreno em que tiver construção ou benefícios.<br/>");
        texto.append("   8. Só poderá transferir o domínio útil do terreno ou parte dele, mediante licença do Prefeito Municipal, a quem a solicitará previamente.<br/>");
        texto.append("   9. Ser-lhe-á facultada recisão deste contrato, quando isso lhe convenha certificando o Prefeito desta sua resolução e pagando previamente todos os fôros e taxas devidas pela posse anterior.<br/>");
        texto.append("   10. Quando realizar a transferência do domínio útil de seu terreno por venda ou docação  pagamento ou outra forma de transferência a que o Município por seu Prefeito renunciar ao direito de opção pagará o laudêmio % sobre o preço do terreno observando o valor real.<br/>");
        texto.append("   11. O aforamento não poderá, em tempo algum ser resgatado pelo foreiro.<br/>");
        texto.append("   12. O foreiro se obriga beneficiar ou construir em seu terreno, nos termos e condições expressas na legislação sob pena das taxas neles consignadas.<br/><br/>");
        texto.append("    E por que pelo mesmo ");
        texto.append(inBoldAndUnderline(foreiro));
        texto.append(" fossem aceitas todas as certidões expostas demais disposições legais obrigando para seu cumprimento todos os seus bens presentes e futuros. Assinam a presente Certidão com o Direito e Encarregado - SCC do DOP (Departamento de Obras Públicas).<br/>");
        texto.append("    Datada e passada em Parnaíba ");
        texto.append(dataPorExtenso(registration.getDataAverbacao()));

        StringBuilder rodape = new StringBuilder("Registrada ao Livro Nº ");
        rodape.append(registration.getLivro());
        rodape.append(" às folhas ");
        rodape.append(registration.getFolhas());
        rodape.append(" em ");
        rodape.append(formatDate(registration.getDataAverbacao()));
        parametros.put("texto", texto.toString());
        parametros.put("rodape", inBold(rodape.toString()));
        parametros.put("numero", registration.getId().toString());
        parametros.put("diretora", configuracaoService.getParameter("diretora_departamento_terras"));
        parametros.put("secretaria", configuracaoService.getParameter("secretaria_regularizacao_fundiaria_habitacao"));
        parametros.put("situacao", registration.getSituacao());

        ReportService.genReport(parametros, null, Reports.AVERBACAO_TRANSFERENCIA);
    }

    private void printRegistrationDesmembramento(Registration registration) {
        ReportService.genReport(new HashMap<String, Object>(), null, Reports.AVERBACAO_DESMEMBRAMENTO);
    }

    public String getNomeProprietarios(List<Proprietario> proprietarios) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < proprietarios.size(); i++) {
            if (proprietarios.size() > 1 && i > 0) {
                if (i < proprietarios.size() - 1) {
                    sb.append(", ");
                } else {
                    sb.append(" e ");
                }
            }
            if (proprietarios != null && proprietarios.get(i) != null) {
                if (proprietarios.get(i).getTipoDocumento() != null) {
                    if (proprietarios.get(i).getTipoDocumento().equals(TipoDocumento.CPF)) {
                        sb.append(proprietarios.get(i).getNome());
                    } else {
                        sb.append(proprietarios.get(i).getNomeFantasia());
                    }
                } else {
                    if (proprietarios.get(i).getNome() != null && !proprietarios.get(i).getNome().equals("")) {
                        sb.append(proprietarios.get(i).getNome());
                    } else {
                        sb.append(proprietarios.get(i).getNomeFantasia());
                    }
                }
            }
        }
        return sb.toString().toUpperCase();
    }

    public String formatDate(Date date) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
        if (date != null) {
            return dateFormat.format(date);
        }
        return null;
    }

    private String inBoldAndUnderline(String texto) {
        StringBuilder sb = new StringBuilder("<style isBold='true' isUnderline='true' pdfFontName='Helvetica-Bold'>");
        sb.append(texto);
        sb.append("</style>");
        return sb.toString();
    }

    private String inBold(String texto) {
        StringBuilder sb = new StringBuilder("<style isBold='true' pdfFontName='Helvetica-Bold'>");
        sb.append(texto);
        sb.append("</style>");
        return sb.toString();
    }

    private String getDimensaoPorExtenso(String number) {
        StringBuilder result = new StringBuilder();
        try {
            BigDecimal n = new BigDecimal(number);
            Extenso e = new Extenso(n);
            result.append(e.toString());
            result.append(" metros (");
            result.append(e.DecimalFormat());
            result.append("m);");
            return result.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    private String dataPorExtenso(Date date) {
        DateFormat dfmt = new SimpleDateFormat("d 'de' MMMM 'de' yyyy");
        return dfmt.format(date);

    }
}
